package org.springblade.oa.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.springblade.core.boot.file.BladeFile;
import org.springblade.core.boot.file.BladeFileUtil;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.oa.entity.InvoiceImage;
import org.springblade.oa.mapper.InvoiceImageMapper;
import org.springblade.oa.service.IInvoiceImageService;
import org.springblade.oa.tool.ImageUtil;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author LK
 * @version 1.0.0
 * @Title: InvoiceImageServiceImpl.java
 * @Description: TODO    发票服务服务层实现类
 * @date 2020/4/15 10:57
 */
@Service
@AllArgsConstructor
public class InvoiceImageServiceImpl extends BaseServiceImpl<InvoiceImageMapper, InvoiceImage> implements IInvoiceImageService {

	InvoiceImageMapper invoiceImageMapper;

	/**
	 * 批量保存图片
	 *
	 * @param files
	 * @param invoiceImage
	 * @return
	 */
	@Override
	public boolean saveBatch(MultipartFile[] files, InvoiceImage invoiceImage) {
		if (!ImageUtil.isImageOrPdfOrWord(files)) {
			return false;
		}
		List<InvoiceImage> invoiceImages = new ArrayList<>();
		List<BladeFile> bladeFiles = BladeFileUtil.getFiles(Arrays.asList(files));
		InvoiceImage invoiceImageReal;
		for (BladeFile bladeFile : bladeFiles) {
			invoiceImageReal = new InvoiceImage();
			bladeFile.transfer();
			invoiceImageReal.setBxId(invoiceImage.getBxId());
			invoiceImageReal.setOriginalName(bladeFile.getOriginalFileName());
			invoiceImageReal.setName(bladeFile.getUploadPath().substring(bladeFile.getUploadPath().lastIndexOf("/") + 1));
			invoiceImageReal.setType(BladeFileUtil.getFileExt(bladeFile.getOriginalFileName()));
			invoiceImageReal.setPath(bladeFile.getUploadPath());
			invoiceImageReal.setCreateUser(invoiceImage.getCreateUser());
			invoiceImageReal.setUpdateUser(invoiceImage.getUpdateUser());
			invoiceImageReal.setCreateTime(invoiceImage.getCreateTime());
			invoiceImageReal.setUpdateTime(invoiceImage.getUpdateTime());
			invoiceImageReal.setModelType(invoiceImage.getModelType());
			invoiceImages.add(invoiceImageReal);
		}
		return super.saveBatch(invoiceImages);
	}

	/**
	 * 批量删除图片
	 *
	 * @param ids
	 * @return
	 */
	@Override
	public boolean removeBatchByIds(String ids) {
		//根据id查询图片储存路径
		List<Integer> idList = Func.toIntList(ids);
		InvoiceImage invoiceImage;
		for (Integer id : idList) {
			invoiceImage = super.getById(id);
			//删除对应资源
			ImageUtil.delImage(invoiceImage.getPath());
		}
		return super.removeByIds(Func.toIntList(ids));
	}

	/**
	 * 图片下载
	 *
	 * @param response
	 * @param id
	 * @return
	 */
	@Override
	public void downloadImage(HttpServletResponse response, String id) {
		//根据id查询图片储存路径
		if (StringUtils.isNotBlank(id)) {
			InvoiceImage invoiceImage = super.getById(id);
			ImageUtil.downloadImage(response, invoiceImage.getPath());
		}
	}

	@Override
	public void preView(HttpServletResponse response, String id) {
		//根据id查询图片储存路径
		if (StringUtils.isNotBlank(id)) {
			InvoiceImage invoiceImage = super.getById(id);
			ImageUtil.preView(response, invoiceImage.getPath());
		}
	}

	/**
	 * 批量下载
	 *
	 * @param response
	 * @param ids
	 */
	@Override
	public void downloadBatch(HttpServletResponse response, String ids, String zipName) {
		if (StringUtils.isNotBlank(ids)) {
			List<Integer> idList = Func.toIntList(ids);
			List<String> pathList = new ArrayList<>();
			for (Integer id : idList) {
				InvoiceImage invoiceImage = super.getById(id);
				pathList.add(invoiceImage.getPath());
			}
			ImageUtil.downloadBatch(response, pathList, zipName);
		}
	}

	/**
	 * 批量保存图片
	 *
	 * @param files
	 * @param invoiceImage
	 * @return
	 */
	@Override
	public boolean uploadInvoicePdf(MultipartFile[] files, InvoiceImage invoiceImage) {
		if (!ImageUtil.isImageOrPdfOrWord(files)) {
				return false;
		}
		List<InvoiceImage> invoiceImages = new ArrayList<>();
		List<BladeFile> bladeFiles = BladeFileUtil.getFiles(Arrays.asList(files));
		InvoiceImage invoiceImageReal;
		for (BladeFile bladeFile : bladeFiles) {
			invoiceImageReal = new InvoiceImage();
			String invoiceName = getInvoiceName(bladeFile);
			if (invoiceName!=null){
				String originalFileName = bladeFile.getOriginalFileName();
				String uploadPath = bladeFile.getUploadPath();
				String uploadVirtualPath = bladeFile.getUploadVirtualPath();
				bladeFile.setUploadPath(uploadPath.replace(originalFileName,invoiceName));
				bladeFile.setUploadVirtualPath(uploadVirtualPath.replaceAll(originalFileName,invoiceName));
				bladeFile.setOriginalFileName(invoiceName);
				MultipartFileToFile(bladeFile.getUploadPath(),bladeFile.getFile());
				invoiceImageReal.setName(bladeFile.getOriginalFileName());
			}else {
				bladeFile.transfer();
				invoiceImageReal.setName(bladeFile.getUploadPath().substring(bladeFile.getUploadPath().lastIndexOf("/") + 1));
			}
			invoiceImageReal.setBxId(invoiceImage.getBxId());
			invoiceImageReal.setOriginalName(bladeFile.getOriginalFileName());
			invoiceImageReal.setType(BladeFileUtil.getFileExt(bladeFile.getOriginalFileName()));
			invoiceImageReal.setPath(bladeFile.getUploadPath());
			invoiceImageReal.setCreateUser(invoiceImage.getCreateUser());
			invoiceImageReal.setUpdateUser(invoiceImage.getUpdateUser());
			invoiceImageReal.setCreateTime(invoiceImage.getCreateTime());
			invoiceImageReal.setUpdateTime(invoiceImage.getUpdateTime());
			invoiceImageReal.setModelType(invoiceImage.getModelType());
			invoiceImages.add(invoiceImageReal);
		}
		return super.saveBatch(invoiceImages);
	}

	@Override
	public R isExistInvoicePdf(MultipartFile[] files) {
		List<BladeFile> bladeFiles = BladeFileUtil.getFiles(Arrays.asList(files));
		List<String> fileNames=new ArrayList();
		for (BladeFile bladeFile:bladeFiles){
			String invoiceName = getInvoiceName(bladeFile);
			if (invoiceName!=null)fileNames.add(invoiceName);
		}

		Map<String, List<String>> collect = fileNames.stream().collect(Collectors.groupingBy(String::valueOf));
		ArrayList<String> list = new ArrayList<>();
		for (String s:collect.keySet()){
			if (collect.get(s).size()>1){
				list.add(s);
			}
		}
		if (list.size()>0){
			return R.data(0,"发票号码为"+String.join(",",list)+"的发票上传了多个");
		}
		//跟数据库对比重复发票集合
		if (fileNames.size()>0) {
			List<InvoiceImage> repeatInvoices = this.list(new QueryWrapper<InvoiceImage>().eq("is_deleted", 0).in("name", fileNames));
			if (repeatInvoices.size() > 0) {
				String repeatString = repeatInvoices.stream().map(invoiceImage -> invoiceImage.getName().substring(8)).collect(Collectors.joining(","));
				return R.data(0, "发票号码为" + repeatString + "的发票已上传，请勿重复上传");
			}
		}
		return R.data(1);
	}


	public String getInvoiceName(BladeFile file) {
		PDDocument document = null;
		String invoiceName=null;
		try {
			document = PDDocument.load(file.getFile().getInputStream());
			// 文本内容
			PDFTextStripper stripper = new PDFTextStripper();
			// 设置按顺序输出
			stripper.setSortByPosition(true);
			stripper.setStartPage(1);
			stripper.setEndPage(1);
			String text = stripper.getText(document).replaceAll("\r\n","").replaceAll(" ","");
			int dateIndex = text.indexOf("开票日期") + 5;
			int numberIndex=text.indexOf("发票号码") + 5;
			String date = text.substring(dateIndex,dateIndex+11).trim();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
			SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
			String formatDate = sdf1.format(sdf.parse(date));
			String number = text.substring(numberIndex, numberIndex+8).trim();
			invoiceName= formatDate +number+".pdf";
		} catch (Exception e) {
			return null;
		} finally {
			try {
				if (document != null) {
					document.close();
				}
			} catch (IOException e) {
			}
		}
		return invoiceName;
	}
	public boolean MultipartFileToFile(String path, MultipartFile file) {
		File f = null;
		try {
			if (file != null && file.getSize() > 0) {
				InputStream in = file.getInputStream();
				f = new File(path);
				if (f.exists()){
					return false;
				}
				File pfile = f.getParentFile();
				if (!pfile.exists()) {
					pfile.mkdirs();
				}
				OutputStream os = new FileOutputStream(f);
				int bytesRead;
				byte[] buffer = new byte[8192];
				while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
					os.write(buffer, 0, bytesRead);
				}
				in.close();
				os.close();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

}
